package org.gd136.ce.stage;

import java.nio.IntBuffer;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import org.gd136.ce.game.GS;
import org.gd136.ce.manager.RM;
import org.gd136.ce.util.U;

import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.PixmapIO;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.glutils.ImmediateModeRenderer20;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;
import com.badlogic.gdx.math.EarClippingTriangulator;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.InputListener;
import com.badlogic.gdx.scenes.scene2d.ui.Image;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.scenes.scene2d.ui.Label.LabelStyle;
import com.badlogic.gdx.utils.ScreenUtils;

public class LogoDrawLayer extends Layer {

	ShapeRenderer shapeRender;

	BitmapFont font;
	Label pLabel;

	public LogoDrawLayer() {
		super();

		RM.parameter().size = 14;
		RM.parameter().color = Color.BLUE;
		RM.parameter().borderWidth = 0;
		font = RM.generateFont();
		pLabel = new Label("Point[] Color[R:G:B]", new LabelStyle(font,
				Color.WHITE));

		addDisposeSign(font);
		pLabel.setPosition(20, 50);

		// //////
		// Image bg = U.createMask(this);
		// bg.setColor(Color.WHITE);
		// addActor(bg);

		shapeRender = new ShapeRenderer();
		addDisposeSign(shapeRender);

		// ////
		lx = getWidth() / 2;
		ly = getHeight() / 2;
		lr = 58;

		cos = (float) (Math.cos(lr / 2 / (lr * 3.5)));
		off = lr * 1.5f * (float) (Math.cos(lr / 2 / (lr * 1.5)));

		boxW = off / 14;
		boxH = lr / 8;

		addActor(pLabel);
		// //
		int perRotation = 1;
		for (int i = 0; i < 315 - perRotation; i++) {
			float ps[] = polygonG(lx, ly, lr * 3.5f, i, i + perRotation);
			short[] trans = ect.computeTriangles(ps).items;
			points.put(ps, trans);
		}

		// /////

		addOutputPNG();
	}

	public void addOutputPNG() {
		addListener(new InputListener() {
			@Override
			public boolean touchDown(InputEvent event, float x, float y,
					int pointer, int button) {
				return true;
			}

			@Override
			public void touchUp(InputEvent event, float x, float y,
					int pointer, int button) {
				Pixmap pix = ScreenUtils.getFrameBufferPixmap(0, 0, GS.width,
						GS.height);

				IntBuffer buffer = pix.getPixels().asIntBuffer();
				int[] data = new int[GS.width * GS.height];
				int lineBytes = GS.width;
				for (int i = 0; i < GS.height; i++) {
					buffer.position((GS.height - i - 1) * lineBytes);
					buffer.get(data, i * lineBytes, lineBytes);
				}

//				for (int i = 0; i < data.length; i++) {
//					if (data[i] == -1) {
//						data[i] = 0;
//					}
//				}

				buffer.clear();
				buffer.put(data);

				PixmapIO.writePNG(RM.res("LOGO_OUUT.png"), pix);
				pix.dispose();
			}
		});
	}

	float lx, ly, lr;
	float boxW, boxH;
	float cos;
	float off;
	float boxXCount = 14, boxYCount = 8;

	int ttt = 0;
	Map<float[], short[]> points = new HashMap<float[], short[]>();

	EarClippingTriangulator ect = new EarClippingTriangulator();
	ImmediateModeRenderer20 render = new ImmediateModeRenderer20(204800, false,
			true, 0);

	@Override
	public void draw(Batch batch, float parentAlpha) {
		super.draw(batch, parentAlpha);

		render.begin(shapeRender.getProjectionMatrix(),
				ShapeType.Filled.getGlType());
		for (Entry<float[], short[]> part : points.entrySet()) {
			float[] ps = part.getKey();
			short[] trans = part.getValue();
			for (int i = 0; i < trans.length; i++) {
				render.color(greenColorA);
				render.vertex(ps[trans[i] * 2], ps[trans[i] * 2 + 1], 0);
			}
		}
		render.end();

		shapeRender.begin(ShapeType.Filled);

		shapeRender.setColor(greenColorB);
		shapeRender.circle(lx, ly, lr * 1.5f, 200);

		shapeRender.setColor(greenColorA);
		shapeRender.rect(lx + off, ly - lr / 2, lr * 3.5f * cos - off, lr);

		// //////
		shapeRender.setColor(Color.WHITE);
		// 1
		shapeRender.rect(lx + boxW, ly - lr / 2, boxW * 2, lr);
		// 3
		shapeRender.rect(lx + boxW * 4, ly - lr / 2, boxW * 4, boxH * 2);
		shapeRender.rect(lx + boxW * 4, ly - lr / 2 + boxH * 3, boxW * 4,
				boxH * 2);
		shapeRender.rect(lx + boxW * 4, ly - lr / 2 + boxH * 6, boxW * 4,
				boxH * 2);
		shapeRender.rect(lx + boxW * 6, ly - lr / 2, boxW * 2, lr);
		// 6
		shapeRender.rect(lx + boxW * 9, ly - lr / 2, boxW * 2, lr);
		shapeRender.rect(lx + boxW * 9, ly - lr / 2, boxW * 5, boxH * 2);
		shapeRender.rect(lx + boxW * 9, ly - lr / 2 + boxH * 3, boxW * 5,
				boxH * 2);
		shapeRender.rect(lx + boxW * 9, ly - lr / 2 + boxH * 6, boxW * 5,
				boxH * 2);
		shapeRender.rect(lx + boxW * 12, ly - lr / 2, boxW * 2, boxH * 5);

		shapeRender.end();
	}

	Color greenColorA = new Color(52 / 255f, 168 / 255f, 83 / 255f, 1);
	Color greenColorB = new Color(99 / 255f, 234 / 255f, 131 / 255f, 1);

	private float[] polygonG(float x, float y, float r, int rotationMin,
			int rotationMax) {
		float or = r / 3.5f;
		float cr = or * 2.5f;

		int rotation = rotationMax - rotationMin + 1;
		if (rotation > 360) {
			rotation = rotation % 360 + 360;
		}
		float radiansMin = (float) (rotationMin / 180f * Math.PI);
		// float radiansMax = (float) (rotationMax / 180f * Math.PI);

		int pointCount = Math.min(360, Math.max(4, rotation));
		float radd = (float) ((2 * Math.PI) / 360);
		int tpc = Math.max(4, pointCount);
		float[] p = new float[tpc * 2 * 2];

		float roff = (or / 2) / r;
		float radians = roff - radiansMin;
		for (int i = 0; i < tpc; i++) {
			float cx = (float) (r * Math.cos(radians));
			float cy = (float) (r * Math.sin(radians));
			p[i * 2] = x + cx;
			p[i * 2 + 1] = y + cy;
			radians -= radd;
		}
		int poff = p.length / 2;
		for (int i = 0; i < tpc; i++) {
			float cx = (float) (cr * Math.cos(radians));
			float cy = (float) (cr * Math.sin(radians));
			p[poff + i * 2] = x + cx;
			p[poff + i * 2 + 1] = y + cy;
			radians += radd;
		}

		return p;
	}

	@Override
	public void dispose() {
		super.dispose();
		render.dispose();
	}

}
